package playsManager.gui;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

import playsManager.*;
import playsManager.database.*;
import playsManager.domainLogic.*;
import playsManager.utilities.Utilities;

public class GUI implements ActionListener {

	private DomainLogic dl;
	private Database db;
	
	public GUI(DomainLogic dl)
	{
		this.dl = dl;
		this.db = dl.db;
	}
	
	public void showMainWindow()
	{
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run(){
				
				createAndShowGUI();
			}
		});
	}
	
	
	private JFrame mainFrame;
	private JButton buttonView;
	private JButton buttonTheater;
	private JButton buttonAdmin;
	
	//sets up frame then goes to the login
	private void createAndShowGUI()
	{
		mainFrame = new JFrame("Main");
		mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		Container contentPane = mainFrame.getContentPane();
		JPanel mainPanel = new JPanel();
		
		buttonView = new JButton();
		buttonView.setText("search for plays");
		buttonView.addActionListener(this);
		mainPanel.add(buttonView);
		
		buttonTheater = new JButton();
		buttonTheater.setText("login as theater");
		buttonTheater.addActionListener(this);
		mainPanel.add(buttonTheater);
		
		buttonAdmin = new JButton();
		buttonAdmin.setText("login as admin");
		buttonAdmin.addActionListener(this);
		mainPanel.add(buttonAdmin);
		
		contentPane.add(mainPanel);

		mainFrame.pack();
		mainFrame.addWindowListener(new WindowListener()
		{
			@Override
			public void windowActivated(WindowEvent arg0) {}

			@Override
			public void windowClosed(WindowEvent arg0) {}
			
			@Override
			public void windowClosing(WindowEvent arg0) 
			{
				//do not move to windowClosed().
				//windowClosed() is never fired.
				
				try {
					Database.GetInstance().SaveChanges();
				} catch (Exception e) {
					Utilities.ShowErrorMessage("error saving changes to database.");
				}
			}

			@Override
			public void windowDeactivated(WindowEvent arg0) {}

			@Override
			public void windowDeiconified(WindowEvent arg0) {}

			@Override
			public void windowIconified(WindowEvent arg0) {}

			@Override
			public void windowOpened(WindowEvent arg0) {}
		});
		mainFrame.setVisible(true);
	}
	
	public void actionPerformed(ActionEvent evt)
	{
		if(evt.getSource() == buttonView)
		{
			this.<ViewerMenu>showMenu(new IFactory<ViewerMenu>() {
				public ViewerMenu create()
				{
					return new ViewerMenu(dl);
				}
			});	
		}
		else if(evt.getSource() == buttonTheater)
		{
			LogonInfo info = Logon.PromptForLogonInfo();
			if(info != null)
			{
				final TheaterLogon logon = db.LoginAsTheater(info); 
				if(logon != null)
				{
					this.<TheaterMenu>showMenu(new IFactory<TheaterMenu>() {
						public TheaterMenu create()
						{
							return new TheaterMenu(logon, dl);
						}
					});
				}
				else
				{
					playsManager.utilities.Utilities.ShowErrorMessage("could not log on as a theater with the username and password specified");
				}
			}
		}
		else if(evt.getSource() == buttonAdmin)
		{
			LogonInfo info = Logon.PromptForLogonInfo();
			if(info != null)
			{
				final AdminLogon logon = db.LoginAsAdmin(info); 
				if(logon != null)
				{
					this.<AdminMenu>showMenu(new IFactory<AdminMenu>() {
						public AdminMenu create()
						{
							return new AdminMenu(logon, dl);
						}
					});
				}
				else
				{
					playsManager.utilities.Utilities.ShowErrorMessage("could not log on as an administrator with the username and password specified");
				}
			}
		}
		else // if(evt.getSource().getClass() == ViewerMenu.class)
		{
			mainFrame.setVisible(true);
		}
	}
	
	private<T extends IMenu> void showMenu(IFactory<T> factory)
	{
		mainFrame.setVisible(false);
		
		T menu = factory.create();
		menu.Show();
		menu.addCloseListener(this);
	}
}
